#! /usr/bin/env python

# Copyright (C) 2016 Wind River Systems, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

import os
import sys
import socket
import subprocess
import termios

if len(sys.argv) <= 1:
    sys.exit(0)

named_socket = os.getenv("WRL_ASKPASS_SOCKET")
if not named_socket or named_socket == "":
    print('You must specify a named pipe in WRL_ASKPASS_SOCKET.')
    sys.exit(1)

sock_dir = os.path.dirname(named_socket)
sock_name = os.path.basename(named_socket)

# Make sure the socket directory exists
if not os.path.exists(sock_dir):
    os.makedirs(sock_dir)
os.chdir(sock_dir)

if sys.argv[1] == '--server':
    q_cache = {}

    try:
        os.unlink(sock_name)
    except:
        pass

    s = socket.socket(socket.AF_UNIX)
    s.bind(sock_name)
    s.listen(1)
    quit = False
    while not quit:
        conn, addr = s.accept()
        while 1:
            data = conn.recv(1024)
            if not data:
                break
            if data[0] == 'q':
                q = data[1:]
                response = ''
                if q in q_cache:
                    response = q_cache[q]
                #print('Q: "%s"' % q)
                #print('R: "%s"' % response)
                conn.send(response)
                break
            if data[0] == 's':
                res = data.split('\n')
                q = res[0][1:]
                a = res[1]
                q_cache[q] = a
                #print('S: "%s" = "%s"' % (q, q_cache[q]))
                break
            if data[0] == 'd':
                for q in q_cache:
                    if q == 'tty':
                        continue
                    #print('D: "%s" = "%s"' % (q, q_cache[q]))
                    conn.send(q + '\n' + q_cache[q][1:] + '\n')
                break
            if data[0] == 'x':
                #print('quit')
                quit = True
                break
            #print("skip: " + data)
        conn.close()

    sys.exit(0)

if sys.argv[1] == '--quit':
    s = socket.socket(socket.AF_UNIX)
    s.connect(sock_name)
    s.send('x')
    s.close()
    sys.exit(0)

if sys.argv[1] == '--set':
    result = sys.stdin.readline()

    s = socket.socket(socket.AF_UNIX)
    s.connect(sock_name)
    s.send('s' + sys.argv[2] + '\n' + 'A' + result)
    s.close()
    sys.exit(0)

if sys.argv[1] == '--dump':
    s = socket.socket(socket.AF_UNIX)
    s.connect(sock_name)
    s.send('d')
    while 1:
        result = s.recv(1024)
        if not result:
            break
        print(result)
    s.close()
    sys.exit(0)

s = socket.socket(socket.AF_UNIX)
s.connect(sock_name)
s.send('q' + sys.argv[1])
result = s.recv(1024)
s.close()
if result:
    print(result[1:])
    sys.exit(0)

s = socket.socket(socket.AF_UNIX)
s.connect(sock_name)
s.send('qtty')
tty_file = s.recv(1024)[1:]
s.close()

if not tty_file:
    tty_file = "/dev/tty"

with open(tty_file, 'rw+') as tty_fd:
    if not tty_fd.isatty():
        # Only operate on a tty
        sys.exit(1)

    question = sys.argv[1]

    if question.startswith('Password') or question.endswith('password: '):
        fd = tty_fd.fileno()
        old = termios.tcgetattr(fd)
        new = termios.tcgetattr(fd)

        try:
            # Disable echoing and signals
            # If we don't disable signals, readline can get confused and
            # 'break' the terminal, this way the user MUST enter 'something'
            new[3] &= ~termios.ECHO
            new[3] &= ~termios.ISIG
            termios.tcsetattr(fd, termios.TCSADRAIN, new)
            if termios.tcgetattr(fd)[3] != new[3]:
                tty_fd.write("WARNING: Password may echo to the screen!\n")
            tty_fd.write(question)
            result = tty_fd.readline()
            tty_fd.write('\n')
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old)
    else:
        tty_fd.write(question)
        result = tty_fd.readline()

s = socket.socket(socket.AF_UNIX)
s.connect(sock_name)
s.send('s' + question + '\n' + 'A' + result)
s.close()

s = socket.socket(socket.AF_UNIX)
s.connect(sock_name)
s.send('q' + sys.argv[1])
result = s.recv(1024)
s.close()
if result:
    print(result[1:])
